<!--
//0203002E00010000 -> 02030288909A28 len=14
//0203002E00020000 -> 0203048890010E62EA   len=18
//0203007600020000 -> 
d2e2f   基本
d3031   设定温度
d7677   测量温度
d7879
d7a7b  功率  1=10% 2=17% 3=30% 4=60% 5=100%

更新策略
// 每隔5秒，刷新5台设备。
// 在线设备优先刷新
// 不在线设备，久一点刷新。


分组
一个循环滚动的网页，里面是若干个正方形色块。
顶部可以添加分组，搜索分组。

电源
设定温度
当前温度（）
工作模式
风速大小
风速模式

-->
<!DOCTYPE html>
<html>

<head>
    <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no">
    <meta charset="utf-8" />
    <title>控制面板</title>
    <link href="css/animate.css" rel="stylesheet">
    <link href="css/h5.common.css?1" rel="stylesheet">
    <link href="css/iconfont.css" rel="stylesheet">
    <script src="js/jquery_2_1_4.js" type="text/javascript"></script>
    <script src="js/h5.common.js" type="text/javascript"></script>
    <script src="../public/js/utilsx.js"></script>
    <!-- <script src="js/vue.min.js" type="text/javascript"></script> -->
    <script src="js/vue.js"></script>
    <script src="js/common.js" type="text/javascript"></script>
    <script src="js/vue-lazyload.js" type="text/javascript"></script>
    <script src="js/axios.min.js" type="text/javascript"></script>
    <script src="js/vux.common.js" type="text/javascript"></script>
    <link href="css/vux.common.css" rel="stylesheet">
    <link href="js/swiper4/css/swiper.min.css" rel="stylesheet">
    <script type="application/javascript" src="js/swiper4/js/swiper.min.js"></script>
    <script src="js/vconsole.min.js" type="text/javascript"></script>
    <script src="js/qs.min.js" type="text/javascript"></script>
    <script src="js/element_index.js" type="text/javascript"></script>
    <link href="css/elm_index.css" rel="stylesheet">
    <!--    <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
    <script src="https://unpkg.com/element-ui/lib/index.js"></script> -->
    <script>
        // var vConsole = new VConsole();
    </script>
    <style type="text/css">
    body {
        font-size: 14px;
        width: 10rem;
        margin: 0 auto;
        position: relative;
        background-color: #f5f5f5;
    }

    .menu-div {
        position: fixed;
        left: 0rem;
        top: 0rem;
        width: 1rem;
        bottom: 0rem;
        background-color: #262626;
    }

    .menu-item {
        position: relative;
        font-size: 0.6rem;
        width: 100%;
        height: 100%;
        left: 0.2rem;
        margin-bottom: 0.5rem;
        /* left: 0.1rem;
        padding-top: 0.5rem;
        top: 1rem;*/
    }

    .icon-item {
        position: relative;
        width: 100%;
        height: 100%;
        top: 0;
        left: 0;
        font-size: 0.4rem;

    }

    .menu-active {
        color: #1fb922
            /*background-color:rgba(0,0,0,0);*/
    }

    .menu-unactive {
        color: #fff
            /*background-color:rgba(0,0,0,0);*/
    }

    .menus {
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        -webkittransform: translateY(-50%);
    }

    .menu-exit {
        position: absolute;
        bottom: 0.2rem;
        text-align: center;
        width: 100%;
        color: #fff;
    }

    .menu-exit:active {
        color: #1fb922;
    }

    .main-content {
        position: fixed;
        left: 1rem;
        top: 0;
        right: 0;
        bottom: 0;
        background-color: #fbfbfb;
    }

    .common-btn {
        background-color: #fff;
        border: 1px solid #e5e5e5;
        border-radius: 1px;
        color: #000;
        text-align: center;
        line-height: 40px;
        font-size: 14px;
    }

    .reload-device-btn {
        position: absolute;
        right: 260px;
        top: 50px;
        width: 100px;
        height: 40px;
    }

    .add-group-btn {
        position: absolute;
        right: 20px;
        top: 50px;
        width: 100px;
        height: 40px;
    }

    .add-device-btn {
        position: absolute;
        right: 20px;
        top: 50px;
        width: 100px;
        height: 40px;
    }

    .reload-page-btn {
        position: absolute;
        right: 140px;
        top: 50px;
        width: 100px;
        height: 40px;
    }

    .common-btn:active {
        border: 1px solid #fbfbfb;
        background-color: #e5e5e5;
        border: 1px solid #cecece;
    }

    .choose-com {
        position: absolute;
        right: 20px;
        height: 20px;
        font-size: 12px;
        top: 20px;
    }


    .table-main {
        position: absolute;
        top: 100px;
        width: 100%;
    }

    /**  行高 **/
    /*.cell{max-height: 1rem !important;overflow: auto !important;} */
    .el-table td,
    .el-table th {
        padding: 0 !important;
    }

    .pagination {
        position: relative;
        left: 20px;
        top: 10px;
    }

    .group-area {
        /*background-color: #fff;*/
        position: absolute;
        left: 10px;
        right: 10px;
        top: 100px;
        bottom: 10px;
        overflow-y: scroll;
    }

    .group-item {
        position: relative;
        float: left;
        width: 200px;
        height: 180px;
        margin-left: 10px;
        background-color: #2e84d4;
        margin-top: 10px;
        border-radius: 3px;
    }

    .group-item .group-name {
        position: absolute;
        top: 5px;
        left: 5px;
        width: 90%;
        height: 20px;
        color: #fff;
        font-size: 12px;
    }

    .group-item .group-state {
        position: absolute;
        top: 25px;
        left: 5px;
        width: 90%;
        height: 20px;
        color: #fff;
        font-size: 12px;
    }

    .group-item .group-edit {
        position: absolute;
        top: 5px;
        right: 5px;
        width: 30px;
        height: 30px;
        color: #fff;
        font-size: 28px;
    }

    .group-item .group-delete {
        position: absolute;
        bottom: 5px;
        right: 5px;
        width: 30px;
        height: 30px;
        color: #fff;
        font-size: 28px;
    }

    .group-item .group-edit:active {
        color: #666;
    }

    .group-item .group-delete:active {
        color: #666;
    }

    .group-item .group-power {
        position: absolute;
        bottom: 5px;
        left: 5px;
        width: 50px;
        height: 50px;
        color: #fff;
        font-size: 48px;
    }

    .group-item .group-power:active {
        color: #666;
    }

    .group-item .group-setting {
        position: absolute;
        top: 50px;
        left: 5px;
        width: 100px;
        height: 40px;
        font-size: 14px;
    }

    .setting-btn-common {
        position: relative;
        float: left;
        width: auto;
        margin-left: 10px;
        margin-top: 5px;
        width: 100px;
        height: 40px;
        line-height: 40px;
        background-color: #fff;
        border: 1px solid #e5e5e5;
        border-radius: 1px;
        color: #000;
        text-align: center;
        font-size: 14px;
    }


    .setting-btn-common:active {
        border: 1px solid #fbfbfb;
        background-color: #e5e5e5;
        border: 1px solid #cecece;
    }
    </style>
</head>

<body style="background-color: #eee;font-size: 14px;width: 100%;">
    <div id='app'>
        <div class="menu-div">
            <div class="menus">
                <div class="menu-item">
                    <div v-if="menu_index!=0" class="icon-item iconfont menu-unactive" v-on:click="menu_index=0">&#xe647</div>
                    <div v-if="menu_index==0" class="icon-item iconfont menu-active" v-on:click="menu_index=0">&#xe60c</div>
                </div>
                <div class="menu-item">
                    <div v-if="menu_index!=1" class="icon-item iconfont menu-unactive" v-on:click="menu_index=1">&#xe65c</div>
                    <div v-if="menu_index==1" class="icon-item iconfont menu-active" v-on:click="menu_index=1">&#xe600</div>
                </div>
            </div>
            <div class="menu-exit" v-on:click="btn_action('退出')">退出</div>
        </div>
        <div class="main-content" v-show="menu_index==0">
            <div class="common-btn reload-device-btn" v-on:click="btn_action('刷新数据')">刷新数据</div>
            <div class="common-btn add-device-btn" v-on:click="btn_action('添加设备')">添加设备</div>
            <div class="common-btn reload-page-btn" v-on:click="btn_action('刷新页面')">刷新页面</div>
            <div class="choose-com">
                <label for="disabledSelect">选择串口</label>
                <select name="ports-choice" v-model="comName" @change="port_change">
                    <option :value="item.comName" v-for="item in ports">{{item.comName}}</option>
                </select>
            </div>
            <div style="position: absolute;right: 0px;color: #f04;bottom:0px;">{{port_msg}}</div>
            <!-- {{utilsx}} -->
            <!-- {{device_list}} -->
            <div>
                <div style="margin-top: 20px;margin-bottom: 20px;text-align: right;">
                </div>
                <div class="table-main">
                    <el-table ref="multipleTable" :stripe="true" :fit="true" :data="device_list_page" border tooltip-effect="dark" style="width: 100%" @selection-change="handleSelectionChange" header-cell-class-name="header-row" max-height="390" :row-class-name="tableRowClassName">
                        <el-table-column type="selection" width="55">
                        </el-table-column>
                        <el-table-column label="设备编号" width="60">
                            <template slot-scope="scope">{{ render_item('dnum', scope.row.dnum)}}</template>
                        </el-table-column>
                        <el-table-column label="名称备注" width="100">
                            <template slot-scope="scope">
                                <el-button @click="row_item_click('memo',scope.row)" type="text" size="small">{{ render_item('memo', scope.row.memo)}}</el-button>
                            </template>
                            <!-- <template slot-scope="scope">{{ render_item('memo', scope.row.memo)}}</template> -->
                        </el-table-column>
                        <el-table-column label="是否可控" width="80">
                            <template slot-scope="scope">
                                <div style=" width: 100%;text-align: center;">
                                    <div v-if="!scope.row.is_online" style="width: 16px;height: 16px;border-radius: 8px;background-color: #f04;position: relative;left: 50%;transform: translateX(-50%);"></div>
                                    <div v-if="scope.row.is_online" style="width: 16px;height: 16px;border-radius: 8px;background-color: #0f4;position: relative;left: 50%;transform: translateX(-50%);"></div>
                                </div>
                            </template>
                        </el-table-column>
                        <el-table-column label="电源" width="150">
                            <template slot-scope="scope">
                                <el-button @click="row_item_click('is_power',scope.row)" type="text" size="small">
                                    {{ render_item('is_power', scope.row)}}
                                </el-button>
                            </template>
                        </el-table-column>
                        <el-table-column label="设定温度" width="80">
                            <template slot-scope="scope">
                                <el-button @click="row_item_click('setting_temperature',scope.row)" type="text" size="small">{{ render_item('setting_temperature', scope.row)}}</el-button>
                            </template>
                        </el-table-column>
                        <el-table-column label="测量温度" width="80">
                            <template slot-scope="scope">{{ render_item('measuring_temperature', scope.row)}}</template>
                        </el-table-column>
                        <el-table-column label="工作模式" width="60">
                            <template slot-scope="scope">
                                <el-button @click="row_item_click('work_mode',scope.row)" type="text" size="small">{{ render_item('work_mode', scope.row)}}</el-button>
                            </template>
                        </el-table-column>
                        <el-table-column label="功率" width="60">
                            <template slot-scope="scope">{{ render_item('e_power', scope.row)}}</template>
                        </el-table-column>
                        <el-table-column label="风速模式" width="60">
                            <template slot-scope="scope">
                                <el-button @click="row_item_click('wind_mode',scope.row)" type="text" size="small">{{ render_item('wind_mode', scope.row)}}</el-button>
                            </template>
                        </el-table-column>
                        <el-table-column label="风速大小" width="60">
                            <template slot-scope="scope">
                                <el-button @click="row_item_click('wind_type', scope.row)" type="text" size="small">{{ render_item('wind_type', scope.row)}}</el-button>
                            </template>
                        </el-table-column>
                        <el-table-column fixed="right" label="操作" width="150">
                            <template slot-scope="scope">
                                <!-- <el-button @click="handleClick(scope.row)" type="text" size="small">查看</el-button> -->
                                <!-- <el-button type="text" size="small">编辑</el-button> -->
                                <el-button @click="row_btn_click(scope.row,'删除')" type="text" size="small">删除</el-button>
                                <el-button @click="row_btn_click(scope.row,'刷新')" type="text" size="small">刷新</el-button>
                                <el-button @click="row_btn_click(scope.row,'复位')" type="text" size="small">复位</el-button>
                            </template>
                        </el-table-column>
                    </el-table>
                    <el-pagination class="pagination" background layout="prev, pager, next" :total="device_list.length" :current-page="pageIndex" :page-size="pageSize" @current-change="pageCurrentChange" @prev-click="pagePrevClick()" @next-click="pageNextClick()">
                </div>
                </el-pagination>
            </div>
        </div>
        <div class="main-content" v-show="menu_index==1">
            <div class="common-btn add-group-btn" v-on:click="btn_action('添加分组')">添加分组</div>
            <div class="group-area">
                <!-- 
1.批量操作设备
2.展示 共几个设备，当前几个设备在线。
3.编辑分组信息，设备信息等
4.排序？
-->
                <div v-for="item in group_list" class="group-item">
                    <div class="group-name">名称: {{item.group_name}}</div>
                    <div class="group-state">状态: {{getGroupState(item)}}</div>
                    <div class="group-edit iconfont" v-on:click="btn_action_editgroup(item)">&#xe65c</div>
                    <div class="group-setting common-btn" v-on:click="btn_action_ctlgroup(item)">控制设备</div>
                    <div class="group-power iconfont" v-on:click="btn_action_group_power(item)">&#xe60d</div>
                    <div class="group-delete iconfont" v-on:click="btn_action_delgroup(item)">&#xe638</div>
                </div>
            </div>
        </div>
        <!-- 弹出框1 -->
        <el-dialog :title="addGroupForm.form_title" :visible.sync="addGroupForm.visible">
            <el-form :model="addGroupForm">
                {{addGroupForm.title}}
                <el-form-item label="分组名称" :label-width="addGroupForm.formLabelWidth">
                    <div>
                        <el-autocomplete class="inline-input" v-model="addGroupForm.group_name" :fetch-suggestions="querySearch_group_name" placeholder="请输入内容" @select="handleSelect"></el-autocomplete>
                    </div>
                </el-form-item>
                <el-form-item label="设备编号" :label-width="addGroupForm.formLabelWidth">
                    <div>
                        <el-input class="inline-input" v-model="addGroupForm.group_devices" placeholder="输入逗号分隔设备编号"></el-input>
                    </div>
                </el-form-item>
                <!-- 
                <el-form-item label="单元" :label-width="formLabelWidth">
                    <div>
                        <el-autocomplete class="inline-input" v-model="addForm.unit_name" :fetch-suggestions="querySearch_lib_unit_name" placeholder="请输入内容" @select="handleSelect"></el-autocomplete>
                    </div>
                </el-form-item>
                <el-form-item label="楼层编号" :label-width="formLabelWidth">
                    <div>
                        <el-autocomplete class="inline-input" v-model="addForm.floor_name" :fetch-suggestions="querySearch_lib_floor_name" placeholder="请输入内容" @select="handleSelect"></el-autocomplete>
                    </div>
                </el-form-item>
                <el-form-item label="房间编号" :label-width="formLabelWidth">
                    <el-input v-model="addForm.room_number" auto-complete="off"></el-input>
                </el-form-item>
                <el-form-item label="房间名称" :label-width="formLabelWidth">
                    <el-input v-model="addForm.room_note" auto-complete="off"></el-input>
                </el-form-item>
                -->
            </el-form>
            <div slot="footer" class="dialog-footer">
                <el-button @click="addGroupForm.visible = false">取 消</el-button>
                <el-button type="primary" @click="btn_action_group_submit()">确 定</el-button>
            </div>
        </el-dialog>
        <!-- 弹出框2 控制设备 -->
        <el-dialog :title="settingPop.title" :visible.sync="settingPop.visible">
            <div>
                <div>电源: {{settingState.is_power?'开':'关'}}</div>
                <div>设定温度: {{settingState.setting_temperature}}</div>
                <div>测量温度: {{settingState.measuring_temperature}}</div>
                <div>工作模式 : {{render_item('work_mode',settingState.work_mode)}}</div>
                <div>风速模式 : {{render_item('wind_mode',settingState.wind_mode)}}</div>
                <div>风速大小 : {{render_item('wind_type',settingState.wind_type)}}</div>
            </div>
            <div style="position: relative;height: 200px;width: 98%;margin-top: 30px;">
                <div class="setting-btn-common" @click="btn_action_pop('电源')"> 电源</div>
                <div class="setting-btn-common" @click="btn_action_pop('设定温度')">设定温度</div>
                <div class="setting-btn-common" @click="btn_action_pop('风速')">风速</div>
                <div class="setting-btn-common" @click="btn_action_pop('工作模式')"> 工作模式</div>
                <div class="setting-btn-common" @click="btn_action_pop('风速模式')"> 风速模式</div>
                <div class="setting-btn-common" @click="btn_action_pop('风速大小')"> 风速大小</div>
            </div>
        </el-dialog>
        <ealert ref="ealertConfirm"></ealert>
        <econfirm ref="eConfirm"></econfirm>
        <einputconfirm ref="eInputConfirm"></einputconfirm>
    </div>
</body>
<script type="text/javascript">
let Datastore = require('nedb');
let path = require('path');
// const { remote } = require('electron')

const devicesdb = new Datastore({ // 设备表
    filename: path.join(__dirname, '../data-devices.db'),
    autoload: true
});
devicesdb.ensureIndex({ fieldName: 'dnum', unique: true }, function(err) {
    if (err) {
        console.log(err)
    }
});
const settingdb = new Datastore({ // 设置表  _id code value
    filename: path.join(__dirname, '../data-setting.db'),
    autoload: true
});
settingdb.ensureIndex({ fieldName: 'code', unique: true }, function(err) {
    if (err) {
        console.log(err)
    }
});

const groupdb = new Datastore({ // 设备表
    filename: path.join(__dirname, '../data-group.db'),
    autoload: true
});

let serialport = require('serialport');
let port = null;

Vue.use(VueLazyload)
Vue.prototype.msgboxEx = function(msg, arg) {
    if (typeof(arg) == 'undefined') { arg = 'info' }
    Vue.prototype.$message({
        showClose: true,
        message: msg,
        type: arg
    });
}
// Vue.config.devtools = true
var vm = new Vue({
    el: '#app',
    data: function() {
        return {
            isScanHex: false, //搜索设备，需要转16进制吗？
            menu_index: 0, //左侧menu选中
            ports: [], //当前存在的串口
            comName: '', //串口名称
            portObj: null, //串口对象
            baudrate: 9600, //波特率 9600
            port_msg: '',
            utilsx: utilsx,
            device_list: [],
            group_list: [],
            debug: true,
            pageSize: 10, //10条数据每页
            pageIndex: 1,
            addGroupForm: {
                title: '添加分组',
                type: '添加', //编辑
                visible: false,
                formLabelWidth: '100px',
                group_name: '',
                group_devices: '',
                _id: -1,
            },
            settingPop: {
                title: '控制设备',
                visible: false,
                dots: '',
                device_list: [],
            }
        }
    },
    created: function() {},
    computed: {
        settingState: function() { //获取设置状态
            var vm = this
            var ret = {
                is_online: false, // 是否在线
                is_power: false, // 电源开关
                setting_temperature: 0, // 设定温度
                measuring_temperature: 0, // 测量温度
                work_mode: 0, // 0制热 1制冷
                wind_mode: 0, // 0自动 1手动
                wind_type: 0, // 1高速 2中速 3低速
            }
            for (var i = 0; i < vm.settingPop.device_list.length; i++) {
                var item = vm.settingPop.device_list[i]
                if (item.is_online) {
                    ret.is_online = true
                    var i2e2f = parseInt(item.d2e2f, 16)
                    var id3031 = parseInt(item.d3031, 16)
                    var id7677 = parseInt(item.d7677, 16)
                    ret.is_power = ((i2e2f & 0x0800) == 0x0800) ? 1 : 0;
                    ret.setting_temperature = (id3031 / 10).toFixed(1)
                    ret.measuring_temperature = (id7677 / 10).toFixed(1)
                    ret.work_mode = ((i2e2f & 0x0080) == 0x0080) ? 1 : 0;
                    ret.wind_mode = ((i2e2f & 0x8000) == 0x8000) ? 1 : 0;
                    if ((i2e2f & 0x4000) == 0x4000) {
                        ret.wind_type = 3
                    }
                    if ((i2e2f & 0x2000) == 0x2000) {
                        ret.wind_type = 2
                    }
                    if ((i2e2f & 0x1000) == 0x1000) {
                        ret.wind_type = 1
                    }
                    return ret;
                }
            }
            return ret
        },
        // vm.settingPop.device_list 

        groups: function() {
            var vm = this
            var ret = []
            ret.push({
                name: '全部',
                list: vm.device_list
            })
            //数据库查询group列表


        },
        device_list_page: function() {
            var vm = this
            if (vm.pageIndex <= 0) {
                vm.pageIndex = 1
            }
            var cnt = vm.device_list.length
            var maxPageIndex = Math.ceil(cnt / vm.pageSize)
            if (vm.pageIndex > maxPageIndex) {
                vm.pageIndex = maxPageIndex
            }
            var start = (vm.pageIndex - 1) * 10
            var end = start + 10
            if (end > cnt) {
                end = cnt
            }
            return vm.device_list.slice(start, end);
        }
    },
    methods: {
        getDnumEntity: function(dnum) {
            var vm = this
            for (var i = 0; i < vm.device_list.length; i++) {
                var item = vm.device_list[i]
                if (item.dnum == dnum) {
                    return item
                }
            }
            return false
        },
        getDeviceList: function(dots) { //获取逗号分隔的设备列表
            var vm = this
            var list = dots.split(',')
            var ret = []
            for (var i = 0; i < list.length; i++) {
                var item = vm.getDnumEntity(list[i])
                if (item) {
                    ret.push(item)
                }
            }
            return ret;
        },
        getGroupState: function(item) {
            var vm = this
            // 共几台设备，在线几台设备。
            var dots = item.group_devices; // 
            var list = vm.getDeviceList(dots); //设备列表
            var cnt = 0
            for (var i = 0; i < list.length; i++) {
                var ent = list[i]
                if (ent.is_online) {
                    cnt = cnt + 1
                }
            }
            var s = ''
            s = s + '共' + list.length + '台设备,在线' + cnt + '台'
            return s
        },
        settingSet: function(key, value) {
            var vm = this
            settingdb.findOne({ code: key }, function(err, record) {
                if (!err && record) {
                    var update_fields = {
                        value: value
                    }
                    settingdb.update({ _id: record._id }, { $set: update_fields }, { multi: true }, function(err, numReplaced) {});
                } else {
                    settingdb.insert({ code: key, value: value }, function(err, new_doc) {});
                    return;
                }
            });
        },
        settingGet: function(key, callback) {
            settingdb.findOne({ code: key }, function(err, record) {
                if (!err && record && record.value) {
                    var value = record.value
                    if (value) {
                        callback(value)
                        return;
                    } else {
                        callback('')
                        return;
                    }
                }
            });
        },
        handleSelect: function(item) {
            console.log(item);
        },
        querySearch_group_name(queryString, cb) {
            // var restaurants = this.lib_building_name;
            // var results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants;
            // console.log(results)
            // cb(results);
            cb([]);
        },
        pageCurrentChange: function(n) {
            this.pageIndex = n
        },
        pagePrevClick: function() {
            // alert(2)
        },
        pageNextClick: function() {
            // alert(3)
        },
        auto_connect_serial: function() {
            var vm = this
            if (!vm.portObj) {
                settingdb.findOne({ code: 'LAST_COM_NAME' }, function(err, record) {
                    if (!err && record && record.value) {
                        var lastComName = record.value
                        for (var i = 0; i < vm.ports.length; i++) {
                            if (vm.ports[i].comName == lastComName) {
                                vm.comName = vm.ports[i].comName
                                vm.open_port()
                                return;
                            }
                        }
                    }
                });
            }
        },
        checkOpenPort: function() {
            var vm = this
            if (!vm.portObj) {
                vm.dialog('提示', '请先打开的串口')
                return false;
            }
            return true
        },
        get_device_info: function(row) {



        },
        handleCommand(command) {
            let vm = this
            let pickedArr = this.multipleSelection
            if (pickedArr.length == 0) {
                vm.msgboxEx('当前没有选中的设备', 'error')
                return
            }
            // var device_ids = ''
            // for (let item of vm.multipleSelection) {
            //     if (device_ids == '') {
            //         device_ids = device_ids + item.dnum
            //     } else {
            //         device_ids = device_ids + ',' + item.dnum
            //     }
            // }
            if (command == '基本设置') {
                // console.log(device_ids)
                // vm.$router.push({ path: '/setting_option', params: { device_ids: device_ids } });
            } else if (command == '开机') {
                vm.operate_device(vm.multipleSelection, '开机', '');
            } else if (command == '关机') {
                vm.operate_device(device_ids, '关机', '');
            } else if (command == '睡眠开启') {
                vm.operate_device(vm.multipleSelection, '睡眠开启', '');
            } else if (command == '睡眠关闭') {
                vm.operate_device(vm.multipleSelection, '睡眠关闭', '');
            } else if (command == '童锁开启') {
                vm.operate_device(vm.multipleSelection, '童锁开启', '');
            } else if (command == '童锁关闭') {
                vm.operate_device(vm.multipleSelection, '童锁关闭', '');
            } else if (command == '制冷') {
                vm.operate_device(vm.multipleSelection, '模式制冷', '');
            } else if (command == '制热') {
                vm.operate_device(vm.multipleSelection, '模式制热', '');
            } else if (command == '设定温度') {
                let row = pickedArr[0]
                let setting_temperature = row.setting_temperature
                let vm = this
                vm.$prompt('请输入设定温度', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    inputPattern: /[\d]+?/,
                    inputErrorMessage: '温度格式不正确',
                    inputValue: setting_temperature,
                    inputType: "number"
                }).then(({ value }) => {
                    vm.operate_device(vm.multipleSelection, "设定温度", value)
                }).catch(() => {
                    console.log("取消")
                });
            }
        },
        handleClick(row) {
            console.log(row);
        },
        row_btn_click(row, kName) {
            let vm = this
            if (kName == '编辑') {

            } else if (kName == '删除') {
                Vue.prototype.$confirm('确定删除该设备?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    devicesdb.remove({ _id: row._id }, {}, function(err, numRemoved) {
                        if (err) {
                            vm.msgboxEx('删除失败', 'error')
                        } else {
                            vm.msgboxEx('删除成功', 'success')
                            vm.reload_devices()
                        }
                    });
                }).catch(() => {

                });
            } else if (kName == '刷新') {
                let vm = this
                if (!vm.checkOpenPort()) {
                    return;
                }
                var dnum = row.dnum
                var _id = row._id
                vm.update_device(row, function() {
                    vm.reload_devices();
                }, 0, 2);
            } else if (kName == '复位') {
                Vue.prototype.$confirm('确定重置该设备数据?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    var dnum = row.dnum
                    var dn = vm.isScanHex ? dnum.toString(16) : dnum + '';
                    if (dn.length == 1) {
                        dn = '0' + dn
                    }
                    var cmd = dn + '10002E000102' + '8890' + '0000' // 操作2e2f3031
                    utilsx.sendOrder(vm.portObj, cmd, 2, function(ret) { //0210002e00010280900000 -> 0210002E000161F3
                        if (ret && ret.msg && ret.msg == 'fail') {
                            return;
                        }
                        if (ret.retCmd.length > 0) {
                            vm.update_device(row, function() {}, 0, 2);
                        }
                    }, 16);
                }).catch(() => {

                });
                return
            }
        },
        operate_device(rows, kname, value) {
            if (rows && typeof(rows.dnum) != 'undefined') {
                rows = [rows]
            }
            var vm = this
            if (!vm.checkOpenPort()) {
                return;
            }
            for (var i = 0; i < rows.length; i++) {
                var row = rows[i]
                if (!row.is_online) {
                    continue;
                }
                if (kname == '关机' || kname == '开机') {
                    var dnum = row.dnum
                    var dn = vm.isScanHex ? dnum.toString(16) : dnum + '';
                    if (dn.length == 1) {
                        dn = '0' + dn
                    }
                    var d2e2f = row.d2e2f; // ef字段的值
                    var di = parseInt(d2e2f, 16) //转换成int
                    if (di == 0) {
                        continue;
                    }
                    // 与 0x0800 或一下
                    if (kname == '关机') {
                        di = di & 0xf7ff
                    } else if (kname == '开机') {
                        di = di | 0x0800
                    }
                    var new_d2e2f = di.toString(16);
                    new_d2e2f = utilsx.strPadding(new_d2e2f, 4) //补至4位
                    //0210002e00010288900000
                    var cmd = dn + '10002e000102' + new_d2e2f + '0000' // 操作2e2f
                    // 发送指令
                    utilsx.sendOrder(vm.portObj, cmd, 2, function(ret) { //0210002e00010280900000 -> 0210002E000161F3
                        if (ret && ret.msg && ret.msg == 'fail') {
                            return;
                        }
                        if (ret.retCmd.length > 0) {
                            vm.update_device(row, function() {}, 1, 2);
                        }
                    }, 16);
                    return
                }
                if (kname == '设定温度') { // 3031

                    value = parseInt(value)
                    if (value > 0) {
                        var dnum = row.dnum
                        var dn = vm.isScanHex ? dnum.toString(16) : dnum + '';
                        if (dn.length == 1) {
                            dn = '0' + dn
                        }
                        var d3031 = row.d3031; // ef字段的值
                        var di = parseInt(d3031, 16) //转换成int
                        var new_d3031 = value.toString(16);
                        new_d3031 = utilsx.strPadding(new_d3031, 4) //补至4位
                        var cmd = dn + '100030000102' + new_d3031 + '0000' // 操作2e2f
                        utilsx.sendOrder(vm.portObj, cmd, 2, function(ret) { //0210002e00010280900000 -> 0210002E000161F3
                            if (ret && ret.msg && ret.msg == 'fail') {
                                return;
                            }
                            if (ret.retCmd.length > 0) {
                                vm.update_device(row, function() {}, 1, 2);
                            }
                        }, 16);
                    }
                }
                if (kname == '模式制冷' || kname == '模式制热') {
                    var dnum = row.dnum
                    var dn = vm.isScanHex ? dnum.toString(16) : dnum + '';
                    if (dn.length == 1) {
                        dn = '0' + dn
                    }
                    var d2e2f = row.d2e2f; // ef字段的值
                    var di = parseInt(d2e2f, 16) //转换成int
                    if (di == 0) {
                        continue;
                    }
                    if (kname == '模式制冷') { //1制冷 0制热
                        di = di | 0x0080 // 0000 0000 1000 0000
                    } else if (kname == '模式制热') {
                        di = di & 0xff7f //1111 1111 0111 0000
                    }
                    var new_d2e2f = di.toString(16);
                    new_d2e2f = utilsx.strPadding(new_d2e2f, 4) //补至4位    0184  0184
                    var cmd = dn + '10002e000102' + new_d2e2f + '0000' // 操作2e2f
                    utilsx.sendOrder(vm.portObj, cmd, 2, function(ret) { //0210002e00010280900000 -> 0210002E000161F3
                        if (ret && ret.msg && ret.msg == 'fail') {
                            return;
                        }
                        if (ret.retCmd.length > 0) {
                            vm.update_device(row, function() {}, 1, 2);
                        }
                    }, 16);
                    return
                }
                if (kname == '风速手动' || kname == '风速自动') { // 0自动 1手动
                    var dnum = row.dnum
                    var dn = vm.isScanHex ? dnum.toString(16) : dnum + '';
                    if (dn.length == 1) {
                        dn = '0' + dn
                    }
                    var d2e2f = row.d2e2f; // ef字段的值
                    var di = parseInt(d2e2f, 16) //转换成int
                    if (di == 0) {
                        continue;
                    }
                    // 与 0x0800 或一下
                    if (kname == '风速自动') {
                        di = di & 0x7fff // 0111 1111 1111 1111
                    } else if (kname == '风速手动') {
                        di = di | 0x8000 // 1000 0000 0000 0000
                    }
                    var new_d2e2f = di.toString(16);

                    new_d2e2f = utilsx.strPadding(new_d2e2f, 4) //补至4位
                    var cmd = dn + '10002e000102' + new_d2e2f + '0000' // 操作2e2f
                    // 0110002e000102 8010 0000
                    utilsx.sendOrder(vm.portObj, cmd, 2, function(ret) { //0210002e00010280900000 -> 0210002E000161F3
                        if (ret && ret.msg && ret.msg == 'fail') {
                            return;
                        }
                        if (ret.retCmd.length > 0) {
                            vm.update_device(row, function() {}, 1, 2);
                        }
                    }, 16);
                    return
                }
                if (kname == '风速高速' || kname == '风速中速' || kname == '风速低速') {
                    // alert(kname)
                    var dnum = row.dnum
                    var dn = vm.isScanHex ? dnum.toString(16) : dnum + '';
                    if (dn.length == 1) {
                        dn = '0' + dn
                    }
                    var d2e2f = row.d2e2f; // ef字段的值
                    var di = parseInt(d2e2f, 16) //转换成int
                    if (di == 0) {
                        continue;
                    }
                    // 与 0x0800 或一下
                    if (kname == '风速高速') {
                        di = di | 0x4000 // 0100 0000 0000 0000 -> 1011 = 0xbfff
                        di = di & 0xdfff
                        di = di & 0xefff
                    } else if (kname == '风速中速') {
                        di = di | 0x2000 // 0010 0000 0000 0000 ->1101 = 0xdfff
                        di = di & 0xbfff
                        di = di & 0xefff
                    } else if (kname == '风速低速') {
                        di = di | 0x1000 // 0001 0000 0000 0000->1110 = 0xefff
                        di = di & 0xbfff
                        di = di & 0xdfff
                    }
                    var new_d2e2f = di.toString(16);
                    new_d2e2f = utilsx.strPadding(new_d2e2f, 4) //补至4位
                    var cmd = dn + '10002e000102' + new_d2e2f + '0000' // 操作2e2f


                    //0110002e000102 ffff 0000
                    // alert(cmd)
                    utilsx.sendOrder(vm.portObj, cmd, 2, function(ret) { //0210002e00010280900000 -> 0210002E000161F3
                        if (ret && ret.msg && ret.msg == 'fail') {
                            return;
                        }
                        if (ret.retCmd.length > 0) {
                            vm.update_device(row, function() {}, 1, 2);
                        }
                    }, 16);
                    return
                }
            }
        },
        row_item_click(kName, row) {
            let vm = this
            if (kName == 'memo') {
                let memo = row.memo
                let vm = this
                vm.$prompt('请输入备注', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    inputValue: memo,
                    inputType: "text"
                }).then(({ value }) => {
                    if (value && value.length > 0) {
                        devicesdb.update({ _id: row._id }, { $set: { "memo": value } }, { multi: true }, function(err, numReplaced) {
                            if (err) {
                                vm.msgboxEx('更新失败', 'error')
                            } else {
                                if (numReplaced > 0) {
                                    vm.msgboxEx('更新成功1', 'success')
                                    vm.reload_devices();
                                }
                            }
                        });
                    } else {
                        vm.msgboxEx('备注不能为空', 'error')
                    }
                }).catch(() => {
                    console.log("取消")
                });
                return;
            }
            // 以下需要在线才能才做
            if (!row.is_online) {
                vm.msgboxEx('该设备不在线', 'error')
                return
            }
            if (kName == 'is_power') {
                if (row.is_online && row.d2e2f) {
                    var d2e2f = row.d2e2f
                    var i2e2f = parseInt(row.d2e2f, 16)
                    var flag = i2e2f & 0x0800
                    // 8890
                    if (flag == 0x0800) {
                        Vue.prototype.$confirm('确定关闭设备?', '提示', {
                            confirmButtonText: '确定',
                            cancelButtonText: '取消',
                            type: 'warning'
                        }).then(() => {
                            vm.operate_device([row], "关机", "")
                        }).catch(() => {

                        });
                    } else {
                        Vue.prototype.$confirm('确定开启设备?', '提示', {
                            confirmButtonText: '确定',
                            cancelButtonText: '取消',
                            type: 'warning'
                        }).then(() => {
                            vm.operate_device([row], "开机", "")
                        }).catch(() => {

                        });
                    }
                }
            }
            if (kName == 'setting_temperature') {
                if (!row.is_online) {
                    vm.msgboxEx('该设备不在线', 'error')
                    return
                }
                if (row.is_online && row.d3031) { // 3031
                    var id3031 = parseInt(row.d3031, 16)
                    let vm = this
                    vm.$prompt('请输入设定温度', '提示', {
                        confirmButtonText: '确定',
                        cancelButtonText: '取消',
                        inputPattern: /[\d]+?/,
                        inputErrorMessage: '温度格式不正确',
                        inputValue: (id3031 / 10),
                        inputType: "number"
                    }).then(({ value }) => {
                        value = parseFloat(value) * 10
                        vm.operate_device(row, "设定温度", value)
                    }).catch(() => {
                        console.log("取消")
                    });
                }
            }
            if (kName == 'work_mode') {
                if (row.is_online && row.d2e2f) { //0x0080
                    var i2e2f = parseInt(row.d2e2f, 16)
                    if ((i2e2f & 0x0080) == 0x0080) { // 制冷
                        Vue.prototype.$confirm('确定将设备模式设置为制热?', '提示', {
                            confirmButtonText: '确定',
                            cancelButtonText: '取消',
                            type: 'warning'
                        }).then(() => {
                            vm.operate_device([row], "模式制热", "")
                        }).catch(() => {

                        });
                    } else { // 制冷
                        Vue.prototype.$confirm('确定将设备模式设置为制冷?', '提示', {
                            confirmButtonText: '确定',
                            cancelButtonText: '取消',
                            type: 'warning'
                        }).then(() => {
                            vm.operate_device([row], "模式制冷", "")
                        }).catch(() => {

                        });
                    }
                }
            }
            if (kName == 'wind_mode') {
                if (row.is_online && row.d2e2f) { //0x0080
                    var i2e2f = parseInt(row.d2e2f, 16)
                    if ((i2e2f & 0x8000) == 0x8000) { // 0自动 1手动
                        Vue.prototype.$confirm('确定将风速模式调整为自动?', '提示', {
                            confirmButtonText: '确定',
                            cancelButtonText: '取消',
                            type: 'warning'
                        }).then(() => {
                            vm.operate_device([row], "风速自动", "")
                        }).catch(() => {

                        });
                    } else {
                        Vue.prototype.$confirm('确定将风速模式调整为手动?', '提示', {
                            confirmButtonText: '确定',
                            cancelButtonText: '取消',
                            type: 'warning'
                        }).then(() => {
                            vm.operate_device([row], "风速手动", "")
                        }).catch(() => {

                        });
                    }
                }
            }
            if (kName == 'wind_type') { // 大中小
                if (row.is_online && row.d2e2f) {
                    var i2e2f = parseInt(row.d2e2f, 16)
                    var mode = 3 // 
                    if ((i2e2f & 0x4000) == 0x4000) {
                        mode = 3
                    } else if ((i2e2f & 0x2000) == 0x2000) {
                        mode = 2
                    } else if ((i2e2f & 0x1000) == 0x1000) {
                        mode = 1
                    }
                    mode = mode + 1
                    if (mode > 3) {
                        mode = 1
                    }
                    var arr = [
                        { mode: 1, name: '低速' },
                        { mode: 2, name: '中速' },
                        { mode: 3, name: '高速' },
                    ]
                    var setObj = { mode: 3, name: '高速' };
                    for (var i = 0; i < arr.length; i++) {
                        var item = arr[i]
                        if (item.mmode == mode) {
                            setObj = item
                            break;
                        }
                    }
                    if (mode == 3) {
                        vm.operate_device([row], "风速高速", "")
                    } else if (mode == 2) {
                        vm.operate_device([row], "风速中速", "")
                    } else if (mode == 1) {
                        vm.operate_device([row], "风速低速", "")
                    }
                }
            }
        },
        render_item(kName, val) {
            var vm = this
            if (kName == 'memo') {
                if (typeof(val) == 'undefined' || val == '') return '添加备注'
                return val;
            }
            if (kName == 'dnum') {
                if (val < 10) {
                    return '00' + val
                } else if (val < 100) {
                    return '0' + val
                }
                return '' + val
            } else if (kName == 'is_online') {
                // 是否在线。如果是1并且24小时内更新过的，就显示1.否则显示0。
                if (val == 1) {
                    return '在线'
                } else {
                    return '离线'
                }
            } else if (kName == 'is_power') {
                var row = val
                if (row.is_online && row.d2e2f) {
                    var i2e2f = parseInt(row.d2e2f, 16)
                    var flag = i2e2f & 0x0800
                    if (flag == 0x0800) {
                        return '开'
                    } else {
                        return '关'
                    }
                } else {
                    return '-'
                }
            } else if (kName == 'setting_temperature') { // 设定温度
                var row = val
                if (row.is_online && row.d3031) { // 3031
                    var id3031 = parseInt(row.d3031, 16)
                    return (id3031 / 10).toFixed(1) + '℃';
                }
                return '-'
            } else if (kName == 'measuring_temperature') { //测量温度
                var row = val
                if (row.is_online && row.d7677) { // 3031
                    var id7677 = parseInt(row.d7677, 16)
                    return (id7677 / 10).toFixed(1) + '℃';
                }
                return '-'
            } else if (kName == 'work_mode') { //0制热 1制冷
                var row = val
                if (row.is_online && row.d2e2f) {
                    var i2e2f = parseInt(row.d2e2f, 16)
                    if ((i2e2f & 0x0080) == 0x0080) { // 0184  = 0000 0001 1000 0100   0000 0000 1000 0000
                        return '制冷'
                    } else {
                        return '制热'
                    }
                } else {
                    return '-'
                }
            } else if (kName == 'wind_mode') { // 0自动 1手动
                var row = val
                if (row.is_online && row.d2e2f) {
                    var i2e2f = parseInt(row.d2e2f, 16)
                    if ((i2e2f & 0x8000) == 0x8000) {
                        return '手动'
                    } else {
                        return '自动'
                    }
                } else {
                    return '-'
                }

            } else if (kName == 'wind_type') { //1 高速 2中速 3低速
                var row = val
                if (row.is_online && row.d2e2f) { //0924 =   0000 1001 0010 0100
                    var i2e2f = parseInt(row.d2e2f, 16)
                    if ((i2e2f & 0x4000) == 0x4000) {
                        return '高速'
                    } else if ((i2e2f & 0x2000) == 0x2000) {
                        return '中速'
                    } else if ((i2e2f & 0x1000) == 0x1000) {
                        return '低速'
                    }
                    return '-'
                } else {
                    return '-'
                }
            } else if (kName == 'e_power') {
                var row = val
                if (row.is_online && row.d7a7b) {
                    var id7a7b = parseInt(row.d7a7b, 16)
                    if (id7a7b == 1) return '10%';
                    if (id7a7b == 2) return '17%';
                    if (id7a7b == 3) return '30%';
                    if (id7a7b == 4) return '60%';
                    if (id7a7b == 5) return '100%';
                }
                return "0%"
            }
            return val
        },
        tableRowClassName({ row, rowIndex }) {
            if (row.is_online == 0) {
                return 'offline-row';
            }
            return '';
        },
        handleSelectionChange(val) {
            this.multipleSelection = val;
        },
        dialog: function(title, content, callback) {
            var vm = this
            vm.$refs.ealertConfirm.showConfirm(title, content, '确定', function() {
                if (callback) {
                    callback();
                }
            });
        },
        confirm: function(title, content, txt1, callback, txt2, cancelback) {
            var vm = this
            vm.$refs.eConfirm.showConfirm(title, content, txt1 || '确定', function() {
                if (callback) {
                    callback();
                }
            }, txt2 || '取消', function() {
                if (cancelback) {
                    cancelback();
                }
            });

        },
        inputdialog: function(title, placeholder, oldValue, txt1, callback, txt2, cancelback) {
            var vm = this
            vm.$refs.eInputConfirm.showConfirm(title, placeholder, oldValue, txt1 || '确定', function(n, o) {
                if (callback) {
                    callback(n, o);
                }
            }, txt2 || '取消', function() {
                if (cancelback) {
                    cancelback();
                }
            });
        },
        btn_action_pop: function(name) {
            var vm = this
            if (vm.settingState.is_online == false) {
                vm.msgboxEx('无在线设备,操作失败', 'info')
                return;
            }
            if (name == '电源') {
                var msg = ''
                var operate = ''
                if (vm.settingState.is_power == 1) { //开着
                    msg = '确定关闭设备?'
                    operate = '关机'
                } else {
                    msg = '确定开启设备?'
                    operate = '开机'
                }
                Vue.prototype.$confirm(msg, '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    vm.operate_device(vm.settingPop.device_list, operate, "")
                }).catch(() => {

                });
            }
            if (name == '设定温度') {
                vm.$prompt('请输入设定温度', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    inputPattern: /[\d]+?/,
                    inputErrorMessage: '温度格式不正确',
                    inputValue: vm.settingState.setting_temperature,
                    inputType: "number"
                }).then(({ value }) => {
                    value = parseFloat(value) * 10
                    vm.operate_device(vm.settingPop.device_list, "设定温度", value)
                }).catch(() => {
                    console.log("取消")
                });
            }
            if (name == '风速') {

            }
            if (name == '工作模式') {
                var work_mode = vm.settingState.work_mode; // 0制热 1制冷
                var msg = ''
                var operate = ''
                if (work_mode == 0) {
                    msg = '确定将设备模式设置为制冷?'
                    operate = '模式制冷'
                } else {
                    msg = '确定将设备模式设置为制热?'
                    operate = '模式制热'
                }
                Vue.prototype.$confirm(msg, '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    vm.operate_device(vm.settingPop.device_list, operate, "")
                }).catch(() => {

                });
            }
            if (name == '风速模式') { // wind_mode: 0, // 0自动 1手动
                var wind_mode = vm.settingState.wind_mode;
                var msg = ''
                var operate = ''
                if (work_mode == 0) {
                    msg = '确定将风速模式调整为手动?'
                    operate = '风速手动'
                } else {
                    msg = '确定将风速模式调整为自动?'
                    operate = '风速自动'
                }
                Vue.prototype.$confirm(msg, '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {
                    vm.operate_device(vm.settingPop.device_list, operate, "")
                }).catch(() => {});
            }
            if (name == '风速大小') { //wind_type: 0, // 1高速 2中速 3低速
                var wind_type = vm.settingState.wind_type;
                wind_type = wind_type + 1
                if (wind_type > 3) {
                    wind_type = 1
                }
                if (wind_type == 3) {
                    vm.operate_device(vm.settingPop.device_list, "风速高速", "")
                } else if (wind_type == 2) {
                    vm.operate_device(vm.settingPop.device_list, "风速中速", "")
                } else if (wind_type == 1) {
                    vm.operate_device(vm.settingPop.device_list, "风速低速", "")
                }
            }
        },
        btn_action_group_power: function(item) {
            var vm = this
            // 获取在线设备数，获取是否有设备在线。
            var dots = item.group_devices; // 
            var list = vm.getDeviceList(dots); //设备列表
            var cnt = 0 //在线的数量
            var power = 0 //开着的数量
            for (var i = 0; i < list.length; i++) {
                var ent = list[i]
                if (ent.is_online) {
                    cnt = cnt + 1
                    var d2e2f = ent.d2e2f
                    var i2e2f = parseInt(d2e2f, 16)
                    var flag = i2e2f & 0x0800
                    if (flag == 0x0800) {
                        power = power + 1
                    }
                }
            }
            if (list.length == 0) {
                vm.msgboxEx('当前分组无设备', 'info')
                return
            }
            if (cnt == 0) {
                vm.msgboxEx('当前分组没有可以操控的设备', 'info')
                return
            }
            if (power > 0) {
                Vue.prototype.$confirm('关闭该分组' + power + '台设备?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {

                }).catch(() => {

                });
            } else {
                Vue.prototype.$confirm('开启该分组' + cnt + '台设备?', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                }).then(() => {

                }).catch(() => {

                });


            }
        },
        btn_action_delgroup: function(item) { //删除分组
            var vm = this
            Vue.prototype.$confirm('确定删除该分组?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                groupdb.remove({ _id: item._id }, {}, function(err, numRemoved) {
                    if (err) {
                        vm.msgboxEx('删除失败', 'error')
                    } else {
                        vm.msgboxEx('删除成功', 'success')
                        vm.reload_groups()
                    }
                });
            }).catch(() => {

            });
        },
        btn_action_ctlgroup: function(item) {
            //批量控制设备
            var vm = this
            vm.settingPop.dots = item.group_devices
            vm.settingPop.device_list = vm.getDeviceList(vm.settingPop.dots);
            vm.settingPop.visible = true;
        },
        btn_action_editgroup: function(item) {
            var vm = this;
            console.log(item)
            vm.addGroupForm.title = '编辑分组'
            vm.addGroupForm.type = '编辑'
            vm.addGroupForm.visible = true
            vm.addGroupForm.group_name = item.group_name
            vm.addGroupForm.group_devices = item.group_devices
            vm.addGroupForm._id = item._id
            console.log(item._id)
        },
        unique_list: function(arr) {
            var hash = [];
            for (var i = 0; i < arr.length; i++) {
                if (hash.indexOf(arr[i]) == -1) {
                    if (arr[i]) {
                        hash.push(arr[i]);
                    }
                }
            }
            return hash;
        },
        dotfilter: function(s) {
            var vm = this
            //将字符串分隔，重组，排序
            var s = s.replace(/，/ig, ',');
            var list = s.split(',')
            list = vm.unique_list(list)
            list.sort()
            return list.join(',')
        },
        btn_action_group_submit: function() {
            var vm = this
            vm.addGroupForm.group_devices = vm.dotfilter(vm.addGroupForm.group_devices)
            if (vm.addGroupForm._id) { //编辑分组
                if (!vm.addGroupForm.group_name) {
                    vm.msgboxEx('分组名称不能为空', 'error')
                    return;
                }
                var update_fields = {
                    group_name: vm.addGroupForm.group_name,
                    group_devices: vm.addGroupForm.group_devices,
                }
                groupdb.update({ _id: vm.addGroupForm._id }, { $set: update_fields }, { multi: true }, function(err, numReplaced) {
                    vm.addGroupForm.visible = false
                    vm.reload_groups()
                });
            } else { //新增分组
                if (!vm.addGroupForm.group_name) {
                    vm.msgboxEx('分组名称不能为空', 'error')
                    return;
                }
                // 检查名称是否存在。如果存在，则不允许添加。
                groupdb.findOne({ name: vm.addGroupForm.group_name }, function(err, record) {
                    if (!err) {
                        if (record && record.value) {
                            vm.msgboxEx('该分组已存在', 'error')
                            return;
                        } else {
                            var group_item = {
                                group_name: vm.addGroupForm.group_name,
                                group_devices: vm.addGroupForm.group_devices,
                            };
                            groupdb.insert(group_item, function(err, new_doc) {
                                vm.reload_groups();
                                vm.addGroupForm.visible = false
                            });
                        }
                    }
                });

            }
        },
        btn_action: function(name) {
            var vm = this;
            console.log(name)
            if (name == '退出') {
                window.location.href = 'login.html'
                return;
            }
            if (name == '刷新页面') {
                window.location.reload()
                return;
            }
            if (name == '刷新数据') {
                if (!vm.portObj) {
                    vm.dialog('提示', '请先打开的串口')
                    return;
                }
                vm.refresh_data(); //刷新所有nedb里面的设备数据
                return;
            }
            if (name == '添加设备') {
                if (!vm.portObj) {
                    vm.dialog('提示', '请先打开的串口')
                    return;
                }
                vm.$prompt('输入编号', '提示', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    inputPattern: /[\d]+?/,
                    inputErrorMessage: '编号格式不正确',
                    // inputValue:,
                    inputType: "number"
                }).then(({ value }) => {
                    var dnum = parseInt(value)
                    if (dnum > 0) {
                        var s = vm.isScanHex ? dnum.toString(16) : dnum + '';
                        if (s.length == 1) {
                            s = '0' + s
                        }
                        devicesdb.find({ dnum: dnum }, function(err, list) {
                            if (!err && list.length > 0) {
                                vm.dialog('提示', '该设备已经添加过了，无需重复添加')
                                return;
                            }
                            // 直接加好设备。然后发起reload比较靠谱。

                            // 
                            if (vm.debug) {
                                let device_item = {
                                    dnum: dnum,
                                    name: s
                                };
                                devicesdb.insert(device_item, function(err, new_doc) {
                                    vm.reload_devices();
                                });
                                return;
                            }
                            //
                            // 020302 8890 9A28
                            var cmd = s + '03002E00020000' //取002e的值
                            utilsx.sendOrder(vm.portObj, cmd, 2, function(ret) {
                                if (ret && ret.msg && ret.msg == 'fail') {
                                    vm.dialog('提示', '未发现此设备')
                                    return;
                                }
                                if (ret.retCmd.length > 0 && ret.retCmd.length == 18) {
                                    var d2e2f = ret.retCmd.substring(6, 10) //0203002E00010000 -> 02030288909A28
                                    var d3031 = ret.retCmd.substring(10, 14) //0203002E00020000 -> 0203048890010E62EA
                                    var dn = vm.isScanHex ? dnum.toString(16) : dnum + '';
                                    if (dn.length == 1) {
                                        dn = '0' + dn
                                    }
                                    let device_item = {
                                        dnum: dnum,
                                        name: dn,
                                        d2e2f: d2e2f,
                                        d3031: d3031,
                                        is_online: true,
                                    };
                                    devicesdb.insert(device_item, function(err, new_doc) {
                                        vm.reload_devices();
                                    });
                                }
                            }, 18);
                        });
                    }
                }).catch(() => {
                    console.log("取消")
                });
                return
            }
            if (name == '添加分组') {
                // 弹出一个窗口，输入  分组名称，分组排序数值，设备编号。
                vm.addGroupForm.group_name = ''
                vm.addGroupForm.type = '添加'
                vm.addGroupForm.title = '添加分组'
                vm.addGroupForm.visible = true
                vm.addGroupForm.group_devices = ''
                vm.addGroupForm._id = ''
            }
        },
        refresh_ports: function() {
            serialport.list((err, ports) => {
                vm.ports = ports;
                vm.auto_connect_serial();
            });
        },
        port_change: function() {
            var vm = this
            if (!vm.portObj) {
                console.log('准备打开串口');
                vm.open_port();
                return;
            } else {
                // 关闭串口
                console.log('准备切换串口');
                if (vm.portObj.closing == false) {
                    vm.portObj.close(function(err) {
                        if (err) throw err;
                        else {
                            console.log('串口已经关闭');
                            vm.portObj = null;
                            vm.port_change();
                        }
                    });
                }
                return;
            }
        },
        save_history_port: function(comName) { //保存起来
            var vm = this
            settingdb.findOne({ code: 'LAST_COM_NAME' }, function(err, record) {
                if (!err && record) {
                    var update_fields = {
                        value: comName
                    }
                    settingdb.update({ _id: record._id }, { $set: update_fields }, { multi: true }, function(err, numReplaced) {});
                } else {
                    settingdb.insert({ code: 'LAST_COM_NAME', value: comName }, function(err, new_doc) {});
                    return;
                }
            });

        },
        open_port: function() { //打开串口
            var vm = this
            if (!vm.comName) {
                vm.dialog('提示', '请选择需要打开的串口')
                return;
            }
            vm.portObj = new serialport(vm.comName, {
                baudRate: parseInt(vm.baudrate)
            });
            vm.portObj.on("open", function(err) {
                if (err) {
                    vm.port_msg = err + "打开串口出错，请重试"
                    console.log(err + "打开串口出错，请重试");
                } else {
                    vm.save_history_port(vm.comName);
                    vm.port_msg = "串口已经打开,波特率" + vm.baudrate
                    vm.refresh_data(); //刷新所有nedb里面的设备数据
                }
            });
            vm.portObj.on('error', function(err) {
                vm.port_msg = err.message
                console.log('Error: ', err.message);
            })
            // 接收信息
            vm.portObj.on('data', function(info) {
                console.log('接收到指令', info)
                // console.log(info) //[2, 3, 2, 136, 144, 154, 40]
                if (utilsx) {
                    utilsx.onreceive(info); //代理接收
                }
            });
        },
        reload_devices: function() {
            var vm = this


            // devicesdb.find({}).sort({ dnum: 1 }).limit(10).exec(function(err, list) {
            //     if (!err && list.length > 0) {
            //         vm.device_list = list
            //     }
            // });

            devicesdb.find({}).sort({ dnum: 1 }).exec(function(err, list) {
                if (!err && list.length > 0) {
                    vm.device_list = list
                }
            });

        },
        update_device: function(row, success, type, priority) { // 刷新一个设备
            if (!type) { // type 1刷新2e2f3031   type = 2 只刷新 767778798081  
                type = 0
            }
            if (!priority) {
                priority = 0
            }
            if (priority == 0 && (utilsx.nowTimestamp() - row.update_time) < 5000) {
                console.log('5秒内刚刷新过，跳过')
                return;
            }
            if (!row.is_online) { //不在线的设备，1分钟刷新一次
                if (priority == 0 && (utilsx.nowTimestamp() - row.update_time) < 60000) {
                    console.log('60秒内，不在线设备跳过刷新')
                    return;
                }
            }
            var vm = this
            var dnum = row.dnum
            var _id = row._id
            var dn = vm.isScanHex ? dnum.toString(16) : dnum + '';
            if (dn.length == 1) {
                dn = '0' + dn
            }
            if (type == 2) {
                vm.upate_767778797a7b(row) //设定温度
                return;
            }
            var cmd = dn + '03002E00020000' //取002e3031的值
            utilsx.sendOrder(vm.portObj, cmd, 1, function(ret) {
                // console.log(ret)
                if (ret && ret.msg && ret.msg == 'fail') {
                    let update_fields = {
                        d2e2f: '',
                        d3031: '',
                        is_online: false,
                        update_time: utilsx.nowTimestamp(),
                    };
                    devicesdb.update({ _id: _id }, { $set: update_fields }, { multi: true }, function(err, numReplaced) {
                        if (err) {
                            // vm.msgboxEx('更新失败', 'error')
                        } else {
                            if (numReplaced > 0) {
                                if (success) {
                                    success();
                                }
                            }
                        }
                    });
                    return;
                }
                if (ret.retCmd.length > 0 && ret.retCmd.length == 18) {
                    var d2e2f = ret.retCmd.substring(6, 10) //0203002E00010000 -> 02030288909A28
                    var d3031 = ret.retCmd.substring(10, 14) //0203002E00020000 -> 0203048890010E62EA
                    let update_fields = {
                        d2e2f: d2e2f,
                        d3031: d3031,
                        is_online: true,
                        'update_time': utilsx.nowTimestamp(),
                    };
                    devicesdb.update({ _id: _id }, { $set: update_fields }, { multi: true }, function(err, numReplaced) {
                        if (err) {
                            vm.msgboxEx('更新失败', 'error')
                        } else {
                            if (numReplaced > 0) {
                                vm.msgboxEx('更新成功2', 'success')
                                vm.reload_devices();
                                if (type == 1) {
                                    return
                                }
                                vm.upate_767778797a7b(row) //设定温度
                            }
                        }
                    });
                }
            }, 18);
        },
        upate_767778797a7b: function(row) {
            var vm = this
            var dnum = row.dnum
            var _id = row._id
            var dn = vm.isScanHex ? dnum.toString(16) : dnum + '';
            if (dn.length == 1) {
                dn = '0' + dn
            }
            var cmd = dn + '03007600030000' //取767778797a7b的值
            utilsx.sendOrder(vm.portObj, cmd, 2, function(ret) {
                if (ret.retCmd.length > 0 && ret.retCmd.length == 22) {
                    var d7677 = ret.retCmd.substring(6, 10) //0203002E00010000 -> 02030288909A28
                    var d7879 = ret.retCmd.substring(10, 14) //0203002E00020000 -> 0203048890010E62EA
                    var d7a7b = ret.retCmd.substring(14, 18)
                    let update_fields = {
                        d7677: d7677,
                        d7879: d7879,
                        d7a7b: d7a7b,
                        is_online: true,
                        'update_time': utilsx.nowTimestamp(),
                    };
                    devicesdb.update({ _id: _id }, { $set: update_fields }, { multi: true }, function(err, numReplaced) {
                        if (err) {
                            vm.msgboxEx('更新失败', 'error')
                        } else {
                            if (numReplaced > 0) {
                                vm.msgboxEx('更新成功3', 'success')
                                vm.reload_devices();
                            }
                        }
                    });
                }
            }, 22);
        },
        update_D002E: function(_id, dnum, success) {
            var vm = this
            var s = vm.isScanHex ? dnum.toString(16) : dnum + '';
            if (s.length == 1) {
                s = '0' + s
            }
            var cmd = s + '03002E00010000' //取002e的值
            utilsx.sendOrder(vm.portObj, cmd, 2, function(ret) {
                // console.log(ret)
                if (ret && ret.msg && ret.msg == 'fail') {
                    // vm.dialog('提示', '未发现此设备')
                    let update_fields = {
                        'D002E': '',
                        'is_online': false,
                        'update_time': utilsx.nowTimestamp(),
                    };
                    devicesdb.update({ _id: _id }, { $set: update_fields }, { multi: true }, function(err, numReplaced) {
                        if (err) {
                            vm.msgboxEx('更新失败', 'error')
                        } else {
                            if (numReplaced > 0) {
                                if (success) {
                                    success();
                                }

                            }
                        }
                    });
                    return;
                }
                if (ret.retCmd.length > 0) {
                    let update_fields = {
                        'D002E': ret.retCmd,
                        'is_online': true,
                        'update_time': utilsx.nowTimestamp(),
                    };
                    devicesdb.update({ _id: _id }, { $set: update_fields }, { multi: true }, function(err, numReplaced) {
                        if (err) {
                            vm.msgboxEx('更新失败', 'error')
                        } else {
                            if (numReplaced > 0) {
                                vm.msgboxEx('更新成功4', 'success')
                                vm.reload_devices();
                            }
                        }
                    });
                }
            }, 14);
        },
        refresh_data: function() { //刷新每个设备的状态
            var vm = this
            devicesdb.find({}).sort({ dnum: 1 }).exec(function(err, list) {
                if (!err && list.length > 0) {
                    vm.device_list = list
                    for (var i = 0; i < list.length; i++) {
                        var row = list[i]
                        vm.update_device(row, function() {}, 0, 0);
                    }
                }
            });
        },
        reload_groups: function() {
            var vm = this
            groupdb.find({}).sort({ sort: 1 }).exec(function(err, list) {
                if (!err && list.length >= 0) {
                    vm.group_list = list
                }
            });
        }
    },
    watch: {
        pageIndex: function(n) {
            // alert(n)
        },
        menu_index: function(n) {
            var vm = this
            vm.settingSet('MENU_INDEX', n)
        }
    },
    mounted: function() {
        var vm = this
        vm.settingGet('MENU_INDEX', function(v) {
            if (v) {
                vm.menu_index = v
            }
        })
        this.$nextTick(function() {
            vm.refresh_ports();
            vm.reload_devices();
            vm.reload_groups();

        })
    }
})
</script>

</html>